#include "GameModel.h"
#include <stdio.h>
#include <QDebug>
#include <time.h>
#include <qmath.h>
#include <string>
#include <list>
using namespace std;


GameModel::GameModel()
{
    //初始化增量  行 列
    //上
    incretDatas[0][0]= -1;
    incretDatas[0][1]= 0;
    //下
    incretDatas[1][0]= 1;
    incretDatas[1][1]= 0;
    //左
    incretDatas[2][0]= 0;
    incretDatas[2][1]= -1;
    //右
    incretDatas[3][0]= 0;
    incretDatas[3][1]= 1;
    //左上
    incretDatas[4][0]= -1;
    incretDatas[4][1]= -1;
    //右下
    incretDatas[5][0]= 1;
    incretDatas[5][1]= 1;
    //左下
    incretDatas[6][0]= 1;
    incretDatas[6][1]= -1;
    //右上
    incretDatas[7][0]= -1;
    incretDatas[7][1]= 1;

    //初始化五元组 水平
    //fiveGroups.clear();
    for(int i = 0; i < BOARD_GRAD_SIZE; i++){
        for(int j = 0; j < BOARD_GRAD_SIZE - 4; j++){
            int a[5][2] = {{i,j},{i,j+1},{i,j+2},{i,j+3},{i,j+4}};
            std::vector<std::vector<int>> pointsList;
            for(int w = 0; w < 5;w++){
                std::vector<int> points;
                for(int h = 0; h < 2; h++){
                    points.push_back(a[w][h]);
                }
                pointsList.push_back(points);
            }
            fiveGroups.push_back(pointsList);
        }
    }
    //垂直
    for(int i = 0; i < BOARD_GRAD_SIZE  - 4; i++){
        for(int j = 0; j < BOARD_GRAD_SIZE; j++){
            //fiveGroups.push_back({{i,j},{i+1,j},{i+2,j},{i+3,j},{i+4,j}});
            int a[5][2] = {{i,j},{i+1,j},{i+2,j},{i+3,j},{i+4,j}};
            std::vector<std::vector<int>> pointsList;
            for(int w = 0; w < 5;w++){
                std::vector<int> points;
                for(int h = 0; h < 2; h++){
                    points.push_back(a[w][h]);
                }
                pointsList.push_back(points);
            }
            fiveGroups.push_back(pointsList);
        }
    }
    //左斜
    for(int i = 0; i < BOARD_GRAD_SIZE  - 4; i++){
        for(int j = 4; j < BOARD_GRAD_SIZE; j++){
           // fiveGroups.push_back({{i,j},{i+1,j-1},{i+2,j-2},{i+3,j-3},{i+4,j-4}});
            int a[5][2] = {{i,j},{i+1,j-1},{i+2,j-2},{i+3,j-3},{i+4,j-4}};
            std::vector<std::vector<int>> pointsList;
            for(int w = 0; w < 5;w++){
                std::vector<int> points;
                for(int h = 0; h < 2; h++){
                    points.push_back(a[w][h]);
                }
                pointsList.push_back(points);
            }
            fiveGroups.push_back(pointsList);
        }
    }
    //右斜
    for(int i = 0; i < BOARD_GRAD_SIZE  - 4; i++){
        for(int j = 0; j < BOARD_GRAD_SIZE - 4; j++){
           // fiveGroups.push_back({{i,j},{i+1,j+1},{i+2,j+2},{i+3,j+3},{i+4,j+4}});
            int a[5][2] = {{i,j},{i+1,j+1},{i+2,j+2},{i+3,j+3},{i+4,j+4}};
            std::vector<std::vector<int>> pointsList;
            for(int w = 0; w < 5;w++){
                std::vector<int> points;
                for(int h = 0; h < 2; h++){
                    points.push_back(a[w][h]);
                }
                pointsList.push_back(points);
            }
            fiveGroups.push_back(pointsList);
        }
    }

//    for(int i =0; i < fiveGroups.size();i++ ){
//        for(int w = 0; w < 5;w++){
//            for(int h = 0; h < 2; h++){
//                printf("%d ",fiveGroups[i][w][h]);
//                fflush(stdout);
//            }
//            printf("\n");
//        }
//    }
    int a = 1;
    int b = 3;
    a = -b;
    qDebug()<<"a"<<a;

}

void GameModel::startGame(GameType type)
{
    gameType = type;
    //初始棋盘
    gameMapVec.clear();
    for(int i = 0; i < BOARD_GRAD_SIZE; i++){
        std::vector<int> lineBoard;
        for(int j = 0; j < BOARD_GRAD_SIZE; j++){
            lineBoard.push_back(0);
        }
        gameMapVec.push_back(lineBoard);
    }

    //如果是AI模式，需要初始化评分数组
    if(gameType == AI){
        scoreMapVec.clear();
        for(int i = 0; i < BOARD_GRAD_SIZE; i++){
            std::vector<int> lineBoard;
            for(int j = 0; j < BOARD_GRAD_SIZE; j++){
                lineBoard.push_back(0);
            }
            scoreMapVec.push_back(lineBoard);
        }
    }
    //黑棋下 true， 白棋下false
    playerFlag = true;

    AICount = 0;
}

void GameModel::actionByPerson(int row, int col)
{
    updateGameMap(row, col);
}

void GameModel::updateGameMap(int row, int col)
{
    if(playerFlag){
        gameMapVec[row][col] = 1; //人 黑子
    }else
        gameMapVec[row][col] = -1;//AI 白子

    //换手
    playerFlag = !playerFlag;
}

bool GameModel::isWin(int row, int col)
{
    int compairValue;
    if(playerFlag){
        //当前是人下棋 黑子 则判断白子
        compairValue = -1;
    }else
        compairValue = 1;
    //四个方向 计数
    int num[4] = {0};
    //行 列 增量
    //int detaRow = 0,detaCol = 0;
    int nexRow,nexCol;
    //i = 0 1 是上下 i = 2 3 左右 i=4 5 左上右下 i= 6 7 左下右上
    for(int i = 0 ; i < 8;i ++){
        nexRow = row;
        nexCol = col;
        do{
            num[i/2]++;//加上自身
            nexRow += incretDatas[i][0];
            nexCol += incretDatas[i][1];
        }while(isInRange(nexRow,nexCol)&& gameMapVec[nexRow][nexCol]== compairValue);
    }

    //判断是否有5个子 每次都加一次自身 所以胜利的数目是6个 大于5
    for(int j = 0; j < 4; j++){
        if(num[j] > 5){
            //赢了
            return true;
            if(playerFlag){
                //白子赢了
            }else{
                //黑子赢了
            }
        }
    }
    return false;
}

bool GameModel::isInRange(int row, int col)
{
    if(row >=0 && row < BOARD_GRAD_SIZE
            && col >=0 && col < BOARD_GRAD_SIZE)
        return true;
    else
        return false;
}

//单步
void GameModel::actionByAI(int &clickRow, int &clickCol)
{
    //计算评分
    //calculateScore(-1);//暂定永远是白棋
    calculateScoreNew(-1);

    int index;
    //如果不止一个 就随机选一个
    if(maxpoint.size() >1){
        srand((unsigned)time(0));
        index = rand() % maxpoint.size();
    }else{
        index = 0;
    }
    clickRow = maxpoint[index][0];
    clickCol = maxpoint[index][1];

    updateGameMap(clickRow,clickCol);
}

//往前多步
void GameModel::actionByAI2(int &clickRow, int &clickCol)
{
    //当前AI反正是后手下
    //不过也来个计数 三次以后 也就是AI下了两次以后开始
    if(++AICount < 3){
        qDebug()<<AICount;
        actionByAI(clickRow,clickCol);
        return;
    }

    //加入启发函数
    pointAndScore res = getMaxEvaluate2(4, -1, -INT_MAX); // 4次比较合适 再多了可能会卡

    if(res.xpoint == -1 || res.ypoint == -1){
        actionByAI(clickRow,clickCol);
        return;
    }
    clickRow = res.xpoint;
    clickCol = res.ypoint;

    qDebug()<<clickRow<<" "<<clickCol<<res.score;

    updateGameMap(clickRow,clickCol);
}

//个人评分计数 ----待优化
void GameModel::calculateScore(int chessColor)
{
    //大概思路 八个方向 进攻：如果往前颜色相同 一个棋子+10*步长 再往前颜色不同或到达边界 不计分并停止向前 空格+5    往前一共走四步
    //               防守：如果往前颜色不同 一个棋子+10*步长 再往前颜色不同或到达边界 不计分并停止向前 空格+5 往前一共走四步
    //               如果第一步往前就是空子 +3 再往前三步 +2 +1 +0 如果遇到子 按照进攻防守的方法 一共也只走四步
    //初始化计数数组
    scoreMapVec.clear();
    for(int i = 0; i < BOARD_GRAD_SIZE; i++){
        std::vector<int> lineBoard;
        for(int j = 0; j < BOARD_GRAD_SIZE; j++){
            lineBoard.push_back(0);
        }
        scoreMapVec.push_back(lineBoard);
    }
    //遍历每一个点的八个方向 八个方向的分数总计为当前的点的分数
    for(int i = 0; i < BOARD_GRAD_SIZE; i++){
        for(int j = 0; j < BOARD_GRAD_SIZE; j++){
            if(gameMapVec[i][j] ==0){
                for(int w = 0; w < 8; w++){
                    //四步
                    int nexRow = i,nexCol = j;
                    int firstcolor = 0;
                    int chessNum = 0;
                    for(int step = 0; step < 4 ;step++){
                        nexRow += incretDatas[w][0];
                        nexCol += incretDatas[w][1];
                        //如果达到边界 跳出
                        if(nexRow < 0 || nexRow >= BOARD_GRAD_SIZE || nexCol < 0 || nexCol >= BOARD_GRAD_SIZE){
                            break;
                        }
                        if(firstcolor == 0){
                            firstcolor = gameMapVec[nexRow][nexCol];
                        }
                        if(firstcolor != 0){
                            chessNum++;
                        }
                        if(gameMapVec[nexRow][nexCol] != 0 && gameMapVec[nexRow][nexCol] == firstcolor){
                            if(firstcolor == chessColor){
                                scoreMapVec[i][j] += 2 * qPow(10,chessNum);
                            }else
                                scoreMapVec[i][j] += qPow(10,chessNum);//10 * chessNum;
                        }
                        else if(gameMapVec[nexRow][nexCol] != 0 && gameMapVec[nexRow][nexCol] != firstcolor){
                            //跳出循环
                            break;
                        }
                        else if(gameMapVec[nexRow][nexCol] == 0 && firstcolor == 0){
                            //第一个就是空格则 每个空格顺序计分 3 2 1 0
                            scoreMapVec[i][j] += 3 - step;
                        }
                        else if(gameMapVec[nexRow][nexCol] == 0 && firstcolor != 0){
                            scoreMapVec[i][j] += 6;
                            //如果中间出现了空格 那对chess的计数清零
                            chessNum = 0;
                        }
//                        if(chessNum == 4 && firstcolor == chessColor){
//                            //赢棋 给一个最大权重
//                            scoreMapVec[i][j] += 10000;
//                        }
                    }
                }
            }
        }
    }


    //
    searchMaxScore();
}

void GameModel::calculateScoreNew(int chessColor)
{
    scoreMapVec.clear();
    //初始化计数数组
    scoreMapVec.clear();
    for(int i = 0; i < BOARD_GRAD_SIZE; i++){
        std::vector<int> lineBoard;
        for(int j = 0; j < BOARD_GRAD_SIZE; j++){
            lineBoard.push_back(0);
        }
        scoreMapVec.push_back(lineBoard);
    }
    //同色 按照个数得分
    int sameColorScore[] = {35,800,15000,800000};
    //
    int oppositeColorScore[] = {15,400,1800,100000};
    //没有棋子得分7
    int nullChessScore = 7;
    //

    //遍历五元组
    for(int i = 0; i < fiveGroups.size();i++){
        //flag1 是否有同色棋，flag 是否有异色棋
        int flag1 =0,flag2 = 0;
        //同色棋个数，异色棋个数
        int num1 = 0,num2 = 0;
        for(int j = 0; j < 5; j++){
            if(gameMapVec[fiveGroups[i][j][0]][fiveGroups[i][j][1]] == chessColor){
                flag1 = 1;
                num1++;
            }else if(gameMapVec[fiveGroups[i][j][0]][fiveGroups[i][j][1]] != 0){//不是空 就是相反色
                flag2 = 1;
                num2++;
            }
        }

        if(flag1 == 1&& flag2 == 0){//只有同色棋
            for(int j = 0; j < 5; j++){
                scoreMapVec[fiveGroups[i][j][0]][fiveGroups[i][j][1]] += sameColorScore[num1 - 1];
            }
        }
        else if(flag1 == 0&& flag2 == 1){//只有异色棋
            for(int j = 0; j < 5; j++){
                scoreMapVec[fiveGroups[i][j][0]][fiveGroups[i][j][1]] += oppositeColorScore[num2 - 1];
            }
        }
        else if(flag1 == 0&& flag2 == 0){//没有棋
            for(int j = 0; j < 5; j++){
                scoreMapVec[fiveGroups[i][j][0]][fiveGroups[i][j][1]] += nullChessScore;
            }
        }
    }
    //如果已经有棋子了，那就分值清空
    for(int i = 0; i < BOARD_GRAD_SIZE; i++){
        for(int j = 0; j < BOARD_GRAD_SIZE; j++){
            if(gameMapVec[i][j] != 0)
                scoreMapVec[i][j] = 0;
        }
    }


    searchMaxScore();
}

void GameModel::searchMaxScore()
{
    //计算结束 遍历找最大值
    int max = -1;
    maxpoint.clear();
    for(int i = 0; i < BOARD_GRAD_SIZE; i++){
        for(int j = 0; j < BOARD_GRAD_SIZE; j++){
            //printf("%6d ",scoreMapVec[i][j]);
           // fflush(stdout);
            if(max < scoreMapVec[i][j]){
                max = scoreMapVec[i][j];
                maxpoint.clear();
                std::vector<int> lineBoard;
                lineBoard.push_back(i);//行 索引
                lineBoard.push_back(j);//列 索引
                maxpoint.push_back(lineBoard);
            }
            else if(max == scoreMapVec[i][j]){
                std::vector<int> lineBoard;
                lineBoard.push_back(i);//行 索引
                lineBoard.push_back(j);//列 索引
                maxpoint.push_back(lineBoard);
            }
        }
       // printf("\n");

    }
    //printf("\n");
}

//极大极小值推断  对方回合找最小值（对方的得分取反的最大值，对方肯定是要下在对他最有利的位置），递归回到当前回合，在上面每个情况下的最小值里面找最大值，就是当前下棋的位置
//参数 向前推测的步长 当前要下的棋子颜色
pointAndScore GameModel::getMaxEvaluate(int leftStep, int color)
{
    //qDebug()<<leftStep<<" "<<color;

    pointAndScore newScore;
    newScore.xpoint = -1;
    newScore.ypoint = -1;
    int maxValue = 0;
    for(int i = 0; i < BOARD_GRAD_SIZE; i++){
        for(int j = 0; j < BOARD_GRAD_SIZE; j++){
            if(gameMapVec[i][j] != 0) continue;//当前位置有棋子则继续
            //如果当前位置距离其他棋子都太远了 就跳过
            int allNum = 0;
            for(int w = 0 ; w < 8;w ++){
                int nexRow = i;
                int nexCol = j;
                for(int h = 0; h < 4;h++){
                    nexRow += incretDatas[w][0];
                    nexCol += incretDatas[w][1];
                    if(isInRange(nexRow,nexCol)&& nexCol >=0 && nexCol < BOARD_GRAD_SIZE && gameMapVec[nexRow][nexCol] != 0){
                        allNum++;
                    }
                }
            }
            if(allNum == 0) {continue;}
            //qDebug()<<"okokok!!!";
            //
            calculateScoreNew(color);//计算分数
            int val = scoreMapVec[i][j];
            //qDebug()<<val;
            gameMapVec[i][j] = color;//先下子 后面再设置回来

            //有5子连珠 得分>=800000 直接返回 不再需要往后面递归了
            if(val >= 800000) {
                 gameMapVec[i][j] = 0;//设置回去
                 newScore.xpoint = i;
                 newScore.ypoint = j;
                 newScore.score = val;
                 return newScore;
            }
            //如果不是最后一步 递归 从后面的分数的最大或最小值 当前分数
            if(leftStep > 1){
                pointAndScore stepScore = getMaxEvaluate(leftStep - 1, -color);

                val = -stepScore.score; //只考虑最后一步得分 对方的最小值 就是负的最大值 对方的最小就是我的最大//退后一步是对方 得分是当前的相反值 再往前又是当前 负负得正 //val = -stepScore.score;只需要考虑最后一步得分？

            }
            if(newScore.xpoint == -1 || val > maxValue){//不考虑相同的情况  //跳出上一层 最小值里面找最大值
                newScore.xpoint = i;
                newScore.ypoint = j;
                newScore.score = val;
                maxValue = val;
                //qDebug()<<leftStep<<newScore.xpoint<<" "<<newScore.ypoint<<" "<<newScore.score;
            }

            gameMapVec[i][j] = 0;//设置回去

        }
    }
    //qDebug()<<newScore.xpoint<<" "<<newScore.ypoint<<" "<<newScore.score;
    return newScore;//可能返回xpoint=-1的情况？
}

//极大极小中 对方回合找极小值 然后回到自己回合极小值中找极大值
//所以 如果自己回合的某一个局面(分支)下，到对方回合循环中计算的值小于之前计算的其他局面中的极小值，那这个局面计算的极小值不会更大了，这个局面再往后的递归都可以取消了，也就是该分支被剪了
//已经遍历过的子节点中得到过的极大值（或极小值）传给未遍历过的节点
//运气好可以省去一些遍历   运气好！！！（和顺序有关）
//极大极小 + α-β剪枝
pointAndScore GameModel::getMaxEvaluate(int leftStep, int color, int passValue)
{
    pointAndScore newScore;
    newScore.xpoint = -1;
    newScore.ypoint = -1;
    int maxValue = -INT_MAX;
    for(int i = 0; i < BOARD_GRAD_SIZE; i++){
        for(int j = 0; j < BOARD_GRAD_SIZE; j++){
            if(gameMapVec[i][j] != 0) continue;//当前位置有棋子则继续
            //如果当前位置距离其他棋子都太远了 就跳过
            int allNum = 0;
            for(int w = 0 ; w < 8;w ++){
                int nexRow = i;
                int nexCol = j;
                for(int h = 0; h < 4;h++){
                    nexRow += incretDatas[w][0];
                    nexCol += incretDatas[w][1];
                    if(isInRange(nexRow,nexCol)&& gameMapVec[nexRow][nexCol] != 0){
                        allNum++;
                    }
                }
            }
            if(allNum == 0) {continue;}
            //qDebug()<<"okokok!!!";
            //
            calculateScoreNew(color);//计算分数
            int val = scoreMapVec[i][j];
            //qDebug()<<val;
            gameMapVec[i][j] = color;//先下子 后面再设置回来

            //有5子连珠 得分>=800000 直接返回 不再需要往后面递归了
            if(val >= 800000) {
                 gameMapVec[i][j] = 0;//设置回去
                 newScore.xpoint = i;
                 newScore.ypoint = j;
                 newScore.score = val;
                 return newScore;
            }
            //如果不是最后一步 递归 从后面的分数的最大或最小值 当前分数
            if(leftStep > 1){
                pointAndScore stepScore = getMaxEvaluate(leftStep - 1, -color,-maxValue);
                if(stepScore.score >= passValue){//α-β剪枝 //当前分支下的分支下计算的最小值<前一个分支下计算的最大值 -stepScore.score <= oldmaxValue(也就是传入的 -passValue) 符号-消除就是了
                    gameMapVec[i][j] = 0;//设置回去
                    newScore.xpoint = i;
                    newScore.ypoint = j;
                    newScore.score = stepScore.score;
                    //这个分支不用再继续for循环了
                    return newScore;
                }
                val = -stepScore.score; //只考虑最后一步得分 对方的最小值 就是负的最大值 对方的最小就是我的最大//退后一步是对方 得分是当前的相反值 再往前又是当前 负负得正 //val = -stepScore.score;只需要考虑最后一步得分？

            }
            if(newScore.xpoint == -1 || val > maxValue){//不考虑相同的情况  //跳出上一层 最小值里面找最大值
                newScore.xpoint = i;
                newScore.ypoint = j;
                newScore.score = val;
                maxValue = val;
                //qDebug()<<leftStep<<newScore.xpoint<<" "<<newScore.ypoint<<" "<<newScore.score;
            }

            gameMapVec[i][j] = 0;//设置回去

        }
    }
    //qDebug()<<newScore.xpoint<<" "<<newScore.ypoint<<" "<<newScore.score;
    return newScore;//可能返回xpoint=-1的情况？
}

//加入启发搜索 对整理局面评分 并排序 方便剪枝
pointAndScore GameModel::getMaxEvaluate2(int leftStep, int color, int passValue)
{
    //在遍历之前 排个序 使用启发搜索
    //list
    list<pointAndScore> pointScore;
    list<pointAndScore>::iterator listP;
    for(int i = 0; i < BOARD_GRAD_SIZE; i++){
        for(int j = 0; j < BOARD_GRAD_SIZE; j++){
            if(gameMapVec[i][j] != 0) continue;//当前位置有棋子则继续
            //如果当前位置距离其他棋子都太远了 就跳过
            int allNum = 0;
            for(int w = 0 ; w < 8;w ++){
                int nexRow = i;
                int nexCol = j;
                for(int h = 0; h < 4;h++){
                    nexRow += incretDatas[w][0];
                    nexCol += incretDatas[w][1];
                    if(isInRange(nexRow,nexCol)&& gameMapVec[nexRow][nexCol] != 0){
                        allNum++;
                    }
                }
            }
            if(allNum == 0) {continue;}

            pointAndScore temp;
            temp.xpoint = i;
            temp.ypoint = j;
            temp.score = evaluatePoint(i,j,color);

            if(pointScore.empty()){
                pointScore.push_back(temp);
                listP = pointScore.begin();
                continue;
            }
            while(listP->score < temp.score && listP != pointScore.begin()){
                listP--;
            }
            while(listP->score > temp.score && listP != pointScore.end()){
                listP++;
            }
            listP = pointScore.insert(listP,temp);
        }
    }

    //和前面的一样 不过是从list里循环
    pointAndScore newScore;
    newScore.xpoint = -1;
    newScore.ypoint = -1;
    int maxValue = -INT_MAX;
    for(listP = pointScore.begin(); listP != pointScore.end(); listP++){
        //printf("%d ",listP->score);
        //fflush(stdout);
        int val = listP->score;
        //qDebug()<<val;
        gameMapVec[listP->xpoint][listP->ypoint] = color;//先下子 后面再设置回来

        //有5子连珠 得分>=800000 直接返回 不再需要往后面递归了
        if(val >= CHENG_5_SCORE) {
             gameMapVec[listP->xpoint][listP->ypoint] = 0;//设置回去
             return *listP;
        }
        //如果不是最后一步 递归 从后面的分数的最大或最小值 当前分数
        if(leftStep > 1){
            pointAndScore stepScore = getMaxEvaluate2(leftStep - 1, -color,-maxValue);
            if(stepScore.score >= passValue){//α-β剪枝 //当前分支下的分支下计算的最小值<前一个分支下计算的最大值 -stepScore.score <= oldmaxValue(也就是传入的 -passValue) 符号-消除就是了
                gameMapVec[listP->xpoint][listP->ypoint] = 0;//设置回去
                //这个分支不用再继续for循环了
                return newScore;
            }
            val = -stepScore.score; //只考虑最后一步得分 对方的最小值 就是负的最大值 对方的最小就是我的最大//退后一步是对方 得分是当前的相反值 再往前又是当前 负负得正 //val = -stepScore.score;只需要考虑最后一步得分？
        }
        if(newScore.xpoint == -1 || val > maxValue){//不考虑相同的情况  //跳出上一层 最小值里面找最大值
            newScore.xpoint = listP->xpoint;
            newScore.ypoint = listP->ypoint;
            newScore.score = val;
            maxValue = val;
            //qDebug()<<leftStep<<newScore.xpoint<<" "<<newScore.ypoint<<" "<<newScore.score;
        }

        gameMapVec[listP->xpoint][listP->ypoint] = 0;//设置回去
    }
    return newScore;
}

//对局面的估值
//己方和对方都评估  求和
int GameModel::evaluatePoint(int xpos, int ypos, int color)
{
    return 6 * f(xpos,ypos,color) - f(xpos,ypos,-color); //己方加重 注重攻击*6 可修改
    // 遍历棋盘，分别对自己和对手的棋子的每一个位置计算f(x)，加到评估值中，空位置不管
}

int GameModel::f(int xpos, int ypos, int color)
{
    //权重？
    int weight = PosValue[xpos][ypos] + 1;//边上也不能放过
    int score = 0;//分数

    //四个方向
    for(int dir = 0; dir < 4; dir++){
        string s = "";
        //以当前点为中心的九个点
        //起始坐标
        int rBegin = xpos + incretDatas[dir*2][0] * 4;
        int cBegin = xpos + incretDatas[dir*2][1] * 4;
        //坐标递增方向
        int rDir = incretDatas[dir * 2 + 1][0];
        int cDir = incretDatas[dir * 2 + 1][1];
        //终止点坐标
        int rEnd = xpos + rDir * 4;
        int cEnd = xpos + cDir * 4;
        //
        int r = rBegin;
        int c = cBegin;
        while(r != rEnd && c != cEnd){
            //没有超出棋盘，自己的颜色记1，空值0；对手-，超出棋盘记#
            if(isInRange(r,c)){
                if(gameMapVec[r][c] == color){
                    s += "1";
                }
                else if(gameMapVec[r][c] == -color){
                    s += "-";
                }
                else
                    s += "0";
            }
            else
                s +="#";

            r += rDir;
            c += cDir;
        }
        //评分
        //1 包含成5 11111
        if(s.find(CHENG_5_STRING) != string::npos){
            score += CHENG_5_SCORE;
        }
        //2 包含活四
        if(s.find(HUO_4_STRING) != string::npos){
            score += HUO_4_SCORE;
        }
        //3 包含 冲4 5种
        if(s.find(CHONG_4_STRING_1_1) != string::npos
            || s.find(CHONG_4_STRING_1_2) != string::npos
            || s.find(CHONG_4_STRING_2_1) != string::npos
            || s.find(CHONG_4_STRING_2_2 )!= string::npos
            || s.find(CHONG_4_STRING_3) != string::npos){

            score += CHONG_4_SCORE;
        }
        //4 包含 单活3
        if(s.find(DAN_HUO_3_STRING) != string::npos){
            score += DAN_HUO_3_SCORE;
        }
        //5 包含 跳活三
        if(s.find(TIAO_HUO_3_STRING_1_1) != string::npos
            ||s.find(TIAO_HUO_3_STRING_1_2) != string::npos){
            score += TIAO_HUO_3_SCORE;
        }
        //6 包含眠三
        if(s.find(MIAN_3_1_1) != string::npos
            ||s.find(MIAN_3_1_2) != string::npos
            ||s.find(MIAN_3_2_1) != string::npos
            ||s.find(MIAN_3_2_2) != string::npos
            ||s.find(MIAN_3_3_1) != string::npos
            ||s.find(MIAN_3_3_2) != string::npos
            ||s.find(MIAN_3_4_1) != string::npos
            ||s.find(MIAN_3_4_2) != string::npos
            ||s.find(MIAN_3_5) != string::npos
            ||s.find(MIAN_3_6) != string::npos){
            score += MIAN_3_SCORE;
        }
        //7 包含活2
        if(s.find(HUO_2_STRING_1) !=string::npos
            ||s.find(HUO_2_STRING_2) !=string::npos
            ||s.find(HUO_2_STRING_3) !=string::npos){
            score += HUO_2_SCORE;
        }
        //8 包含眠2
        if(s.find(MIAN_2_1_1) != string::npos
            ||s.find(MIAN_2_1_2) != string::npos
            ||s.find(MIAN_2_2_1) != string::npos
            ||s.find(MIAN_2_2_2) != string::npos
            ||s.find(MIAN_2_3_1) != string::npos
            ||s.find(MIAN_2_3_2) != string::npos
            ||s.find(MIAN_2_4) != string::npos){
            score += MIAN_2_SCORE;
        }
    }
    //四个方向分数加起来 乘上权重
    return score * weight;

}
